/*
 * @Author: 胡杨
 * @Date: 2019-04-25 11:14:48
 * @Last Modified by:   胡杨
 * @Last Modified time: 2019-04-25 11:14:48
 */
import qs from 'qs';

function isObject(o) {
	// 是否对象
	return Object.prototype.toString.call(o).slice(8, -1) === 'Object'
}

export class Router {
	/**
	 * @class
	 * */
	constructor() {
		this.interceptor = {
			before: null,
			after: null
		}

		this.instance = null
	}

	static getInstance() {
		if (!this.instance) {
			this.instance = new Router()
		}
		return this.instance
	}

	__before(options) {
		if (this.interceptor.before) {
			let newOptions = this.interceptor.before(options)
			if (newOptions) {
				return newOptions
			}
		}
		return options
	}

	__after(options) {
		if (this.interceptor.after) {
			let newOptions = this.interceptor.after(options)
			if (newOptions) {
				return newOptions
			}
		}
		return options
	}
	
	/**
	 * 增加参数到地址
	 * */
	addParams(url, params) {
		let new_url;
		if (url.indexOf('?') === -1) {
			new_url = `${url}?${params}`;
		} else {
			new_url = url.replace('?', `?${params}&`);
		}
		return new_url;
	}

	/**
	 * 保留当前页面，跳转到应用内的某个页面，使用navigateBack可以返回到原页面。
	 * @description navigateTo, redirectTo 只能打开非 tabBar 页面。
	 * @param {Object} options
	 * @param {String}  [options.url] - 地址
	 * @param {String}  [options.animationType] - 动画样式
	 * @param {Number}  [options.animationDuration] - 动画时长
	 * @param {Function}  [options.success] - 执行成功
	 * @param {Function}  [options.fail] - 执行失败
	 * @param {Function}  [options.complete] - 执行结束
	 * @return {Object}
	 */
	navigateTo(
		options = {
			url: '',
			params: {},
			animationType: 'pop-in',
			animationDuration: 300,
			success: () => {},
			fail: () => {},
			complete: () => {}
		}
	) {
		let new_options = this.__before(options);

		if (new_options.url) {
			if (isObject(new_options.params)) {
				new_options.params = qs.stringify(new_options.params);
				new_options.url = this.addParams(new_options.url, new_options.params)
			}
			uni.navigateTo(new_options);
		}

		return this.__after(new_options)
	}

	/**
	 * 关闭当前页面，跳转到应用内的某个页面。
	 * @description navigateTo, redirectTo 只能打开非 tabBar 页面。
	 * @param {*} options
	 */
	redirectTo(
		options = {
			url: '',
			success: () => {},
			fail: () => {},
			complete: () => {}
		}
	) {
		let new_options = this.__before(options);
		
		if (new_options.url) {
			if (isObject(new_options.params)) {
				new_options.params = qs.stringify(new_options.params);
				new_options.url = this.addParams(new_options.url, new_options.params)
			}
			uni.redirectTo(new_options);
		}

		return this.__after(new_options)
	}

	/**
	 * 关闭所有页面，打开到应用内的某个页面。
	 * @description reLaunch 可以打开任意页面。
	 * @param {*} options
	 */
	reLaunch(
		options = {
			url: '',
			success: () => {},
			fail: () => {},
			complete: () => {}
		}
	) {
		let new_options = this.__before(options);

		if (new_options.url) {
			if (isObject(new_options.params)) {
				new_options.params = qs.stringify(new_options.params);
				new_options.url = this.addParams(new_options.url, new_options.params)
			}
			uni.reLaunch(new_options);
		}

		return this.__after(new_options)
	}

	/**
	 * 跳转到 tabBar 页面，并关闭其他所有非 tabBar 页面。
	 * @description switchTab 只能打开 tabBar 页面。
	 * @param {*} options
	 */
	switchTab(
		options = {
			url: '',
			success: () => {},
			fail: () => {},
			complete: () => {}
		}
	) {
		let new_options = this.__before(options);

		if (new_options.url) {
			if (isObject(new_options.params)) {
				new_options.params = qs.stringify(new_options.params);
				new_options.url = this.addParams(new_options.url, new_options.params)
			}
			uni.switchTab(new_options);
		}

		return this.__after(new_options)
	}

	/**
	 * 关闭当前页面，返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈，决定需要返回几层。
	 * @param {*} options
	 */
	navigateBack(
		options = {
			delta: 1,
			animationType: 'pop-out',
			animationDuration: 300
		}
	) {
		let new_options = this.__before(options);

		if (new_options.url) {
			if (isObject(new_options.params)) {
				new_options.params = qs.stringify(new_options.params);
				new_options.url = this.addParams(new_options.url, new_options.params)
			}
			uni.navigateBack(new_options);
		}

		return this.__after(new_options)
	}
}

let _myRouter = Router.getInstance();
export default _myRouter;
